package cn.imusic.discovery.registry.impl;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.ReflectionUtils;

import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.EurekaHttpClient;


public class ImusicEurekaClient extends DiscoveryClient {
  private static final Log log = LogFactory.getLog(ImusicEurekaClient.class);

  private Field eurekaTransportField;
  private ApplicationInfoManager applicationInfoManager;
  private AtomicReference<EurekaHttpClient> eurekaHttpClient = new AtomicReference<EurekaHttpClient>();



  public ImusicEurekaClient(ApplicationInfoManager applicationInfoManager,
      EurekaClientConfig config) {
    super(applicationInfoManager, config);
    this.applicationInfoManager = applicationInfoManager;
    this.eurekaTransportField = ReflectionUtils.findField(DiscoveryClient.class, "eurekaTransport");
    ReflectionUtils.makeAccessible(this.eurekaTransportField);
  }

  public ApplicationInfoManager getApplicationInfoManager() {
    return applicationInfoManager;
  }

  public void cancelOverrideStatus(InstanceInfo info) {
    getEurekaHttpClient().deleteStatusOverride(info.getAppName(), info.getId(), info);
  }

  EurekaHttpClient getEurekaHttpClient() {
    if (this.eurekaHttpClient.get() == null) {
      try {
        Object eurekaTransport = this.eurekaTransportField.get(this);
        Field registrationClientField =
            ReflectionUtils.findField(eurekaTransport.getClass(), "registrationClient");
        ReflectionUtils.makeAccessible(registrationClientField);
        this.eurekaHttpClient.compareAndSet(null,
            (EurekaHttpClient) registrationClientField.get(eurekaTransport));
      } catch (IllegalAccessException e) {
        log.error("error getting EurekaHttpClient", e);
      }
    }
    return this.eurekaHttpClient.get();
  }

  public void setStatus(InstanceStatus newStatus, InstanceInfo info) {
    getEurekaHttpClient().statusUpdate(info.getAppName(), info.getId(), newStatus, info);
  }


}
